// Copyright Leonid Shlyapnikov 2010
// Distributed under the GNU Lesser General Public License http://www.gnu.org/licenses/lgpl.html
//    author: Leonid Shlyapnikov, created on: Feb 17, 2010

#ifndef FIXPARSER_CPP_SRC_MAIN_FIXPARSER_TAG_H_
#define FIXPARSER_CPP_SRC_MAIN_FIXPARSER_TAG_H_

#include <boost/utility.hpp>
#include <boost/mpl/index_of.hpp>
//#include <boost/mpl/is_sequence.hpp>
//#include <boost/mpl/assert.hpp>

#include <string>

#include "./util.h"


namespace fixparser {

/**
 * Represents a registered tag that can be returned by tag ID.
 */
template<size_t TAG_NUM>
class Tag: noninstantiatable {
public:
    typedef Tag<TAG_NUM> type;
    static const size_t tag = TAG_NUM;
};

/**
 * MetaFunction to return an index of a tag from an mpl::list< Tag<N> > (a list of registered tags)
 */
template<size_t TAG_NUM, typename CACHED_TAGS_T>
struct mpl_tag_index {
    typedef typename CACHED_TAGS_T::cached_tags_mpl_list cached_tags_mpl_list;
//    BOOST_MPL_ASSERT( boost::mpl:is_sequence< typename CACHED_TAGS_T::cached_tags_mpl_list > );

    typedef Tag<TAG_NUM> tag;
    static const int result = boost::mpl::index_of< cached_tags_mpl_list, tag >::type::value;
};

size_t get_number_of_decimal_digits(int tagId);

class TagConverter: boost::noncopyable {
public:
    static const TagConverter& instance() {
        static TagConverter instance_;
        return instance_;
    }

    static const std::string& tagIdToString(int indx) {
        return TagConverter::instance().tagIdToStringInternal(indx);
    }

    static const int MIN_TAG_ID = 1;
    static const int MAX_TAG_ID = 9999;

private:
    TagConverter();
    virtual ~TagConverter() {}

    const std::string& tagIdToStringInternal(int indx) const;

    std::string tagIdToStringMap_[MAX_TAG_ID];
};

}

#endif  // FIXPARSER_CPP_SRC_MAIN_FIXPARSER_TAG_H_
